package com.commods.main.view.components.historicalChart.proto.temp
{
	import Commods.Cfp.Dto.HistoricPricesSowRequest;
	import Commods.Cfp.Dto.LoginRequest;
	
	import com.lab49.utils.LogUtils;
	import com.netease.protobuf.WritingBuffer;
	import com.pcbsys.foundation.util.Long;
	import com.pcbsys.nirvana.client.nChannel;
	import com.pcbsys.nirvana.client.nConsumeEvent;
	import com.pcbsys.nirvana.client.nDataStreamListener;
	import com.pcbsys.nirvana.client.nEventListener;
	import com.pcbsys.nirvana.client.nEventProperties;
	import com.pcbsys.nirvana.client.nQueue;
	import com.pcbsys.nirvana.client.nSession;
	import com.pcbsys.nirvana.client.nSessionAttributes;
	import com.pcbsys.nirvana.client.nSessionFactory;
	import com.pcbsys.nirvana.client.nStore;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.IExternalizable;
	
	import mx.events.DynamicEvent;
	import mx.logging.ILogger;
	import mx.logging.Log;
	import mx.utils.UIDUtil;
	
	import org.osmf.logging.Logger;
	
	[Event(name="connected", type="flash.events.Event")]
	[Event(name="responseMessage", type="mx.events.DynamicEvent")]
	//[Event(name="message", type="mx.events.DynamicEvent")]
	
	public class NirvanaServiceConnector extends EventDispatcher implements nDataStreamListener, nEventListener
	{
		private static const LOG:ILogger = LogUtils.getLogger(NirvanaServiceConnector);
		public function NirvanaServiceConnector()
		{
		}
		
		//Eevents
		public static const EVT_CONNECTED:String = "connected";
		public static const EVT_MESSAGE:String = "message";
		public static const EVT_RESPONSE_MESSAGE:String = "responseMessage";
		
		//
		private var _session:nSession;
		private var requestQueue:nQueue;
		
		private var endpointString  :String = "nsp://localhost:9000"; // "nsp://ldn-vm-inn01:9000,nsp://localhost:9000";
		private var appName : String = "tcServer listening stream";
		private var sessionId : String = UIDUtil.createUID();
		
		//{region CLASS_INTERFACE
		[Bindable("connected")]public var connected:Boolean;
		public function connect():void
		{
			connected = false;
			try 
			{
				LOG.debug("Connecting to {0}", endpointString);
				var attributes : nSessionAttributes = new nSessionAttributes(endpointString , 5);
				_session = nSessionFactory.create(attributes, sessionId, appName, onError);
				_session.init(onInit, null, true, this);
				//_session.addEventListener(SessionConnectedE.SESSION_CONNECTED, initialiseLoginMessagingCb);
			}
			catch( e : Error) 
			{
				LOG.fatal("Failed to connect. Reason: {0}", e);
			}
			
		}
		
		private var _requestsRegistry:Dictionary = new Dictionary();
		public function subscribeToService(serviceName:String):void{
			LOG.debug("Subscribe to {}" + serviceName);
			_session.findStore(serviceName + "/Request", onChannelRequestSubscribed);
			_session.findStore(serviceName + "/Response", onChannelResponseSubscribed);
		}
		
		protected function onChannelRequestSubscribed(queue:nStore):void { 
			LOG.debug("Request subscribed");
			requestQueue = queue as nQueue;
		}
		
		protected function onChannelResponseSubscribed(channel:*):void { 
			LOG.debug("Response subscribed");
			var responseChannel:nChannel = channel as nChannel;
			responseChannel.addSubscriber(this, Long.ZERO, _onChannelSubscribed);
		} 
		
		//??
		private function _onChannelSubscribed(evt:*):void{
			LOG.debug("Response POST?subscribed");
		}
		//}endregion
		
		//{region CLASS_INTERFACE particular services (Temporary)
		public function fireHistoricEvent():void{
			if(requestQueue==null)return;
			var hpsr:HistoricPricesSowRequest = new HistoricPricesSowRequest();
			hpsr.commodityName = "CA";
			
			requestQueue.push(_serializeToEvent(hpsr));
		}
		
		public function fireLoginEvent():void{
			if(requestQueue==null)return;
			var loginRequest:LoginRequest = new LoginRequest();
			loginRequest.username = "user1";
			loginRequest.password = "password1";
			
			requestQueue.push(_serializeToEvent(loginRequest));
		}
		//}endregion
		
		//{region SessionCallbacks
		private function onInit(e:*) : void 
		{
			LOG.info("NSession connected to Realm: {0}", _session.realmName);
			connected = true;
			dispatchEvent(new Event(EVT_CONNECTED));	
		}
		
		private function onError(error:Error, brokenFunction:Function):void {
			LOG.error("NSession error: {0}", error);
			connected=false;
		}
		//}endregion
		
		//{region InterfaceCallbacks
		//nDataStreamListener#onMessage
		public function onMessage(event:nConsumeEvent) : void 
		{
			var msgType:String = event.eventTag;
			LOG.info("nDataStreamListener#onMessage {0}", msgType);
			var msgEvent:DynamicEvent = new DynamicEvent(EVT_MESSAGE);
			msgEvent.message = event.eventData;
			dispatchEvent(msgEvent);
		}
		
		//nEventListener#go
		public function go(event:*):void
		{
			LOG.info("nEventListener#go");
			var msgEvent:DynamicEvent = new DynamicEvent(EVT_RESPONSE_MESSAGE);
			msgEvent.message = event.eventData;
			dispatchEvent(msgEvent);
		}
		//}endregion
		
		//{region SERIALIZE
		private function _serializeToEvent(message:com.netease.protobuf.Message):nConsumeEvent{
			var buffer:WritingBuffer = new WritingBuffer();
			message.writeToBuffer(buffer);
			var byteArray:ByteArray = new ByteArray();
			buffer.toNormal(byteArray);
			var properties:nEventProperties = new nEventProperties();
				properties.put("RequestId", UIDUtil.createUID());
			var resultEvent:nConsumeEvent = new nConsumeEvent(null, properties, byteArray); 
			return resultEvent;
		}
		//}endregion
	}

}